package com.benio.ycfdisplayer.displayer;

import android.view.View;

import com.benio.ycfdisplayer.R;

import java.util.ArrayDeque;
import java.util.Queue;

/**
 * A generic class for creating a {@link Request} and loading image into a target.
 * Created by zhangzhibin on 2016/11/2.
 */
public class GenericRequestBuilder implements RequestBuilder {
    private String mUri;
    private DisplayListener mListener;
    private Options mOptions;
    private Executor mExecutor;
    private TargetFactory mTargetFactory;
    private static final Queue<GenericRequestBuilder> POOL = new ArrayDeque<>(0);

    public static GenericRequestBuilder obtain(Executor executor, TargetFactory targetFactory) {
        GenericRequestBuilder builder = POOL.poll();
        if (builder == null) {
            builder = new GenericRequestBuilder();
        }
        builder.init(executor, targetFactory);
        return builder;
    }

    private GenericRequestBuilder() {
        // just create, instances are reused with recycle/init
    }

    private void init(Executor executor, TargetFactory targetFactory) {
        mExecutor = executor;
        mTargetFactory = targetFactory;
    }

    public GenericRequestBuilder uri(String uri) {
        this.mUri = uri;
        return this;
    }

    public GenericRequestBuilder listener(DisplayListener displayListener) {
        this.mListener = displayListener;
        return this;
    }

    public GenericRequestBuilder options(Options options) {
        this.mOptions = options;
        return this;
    }

    public Target into(Target target) {
        Request request = Request.obtain(mUri, target, mOptions, mListener);
        try {
            mExecutor.execute(request);
        } finally {
            request.recycle();
            recycle();
        }
        return target;
    }

    @Override
    public Target into(View view) {
        Target target = (Target) view.getTag(R.id.target);
        if (target == null) {
            // if there is no cache target, we build a new one.
            target = mTargetFactory.build(view);
            // cache target
            view.setTag(R.id.target, target);
        }
        return into(target);
    }

    public void recycle() {
        mUri = null;
        mListener = null;
        mOptions = null;
        mExecutor = null;
        mTargetFactory = null;
        POOL.offer(this);
    }
}